#pragma once
#include <jsoncpp/json/json.h>
#include <iostream>
#include <unistd.h>
#include <string>
#include <cstring>
#include <vector>
#include "Util.hpp"
using namespace std;
#define SEP " "
#define SELLEN strlen(SEP)
#define HEADER "\t\n"
#define HEADERLEN strlen(HEADER)
// #define MYSELF 1
// 添加报头
// 7\t\n10 + 20\t\n
string AddHeader(const string str)
{
    cout << "添加报头前：\n"
         << str << endl;
    ;
    string ret;
    ret += to_string(str.size());
    ret += HEADER;
    ret += str;
    ret += HEADER;
    cout << "添加报头后：\n"
         << ret;

    return ret;
}

// 去报头
// 7\t\n10 + 20\t\n
string DelHeader(const string str, int len)
{
    cout << "去报头前:\n"
         << str;
    string ret = str.substr(str.size() - HEADERLEN - len, len);
    cout << "去报头后:\n"
         << ret << endl;
    return ret;
};

int Parse(string &buffer, string &out)
{
    auto pos = buffer.find(HEADER);
    if (pos == string::npos)
    {
        return -1;
    }
    string stringlen = buffer.substr(0, pos);
    cout << stringlen << endl;
    int len = stoi(stringlen);
    int targetlen = len + 2 * HEADERLEN + stringlen.size();
    if (targetlen > buffer.size())
    {
        return -1;
    }
    out = buffer.substr(0, targetlen);
    buffer.erase(0, targetlen);
    return len;
}

// Request && Response都要提供序列化和反序列化功能
class Request
{
public:
    Request()
    {
    }

    Request(int x, int y, char op)
        : _x(x), _y(y), _op(op) {}

    // x + y
    // struct->string
    bool Serialize(string &out)
    {
#ifdef MYSELF
        out.clear();
        string stringx = to_string(_x);
        string stringy = to_string(_y);
        // 手动序列化
        out = stringx + SEP + _op + SEP + stringy;
        cout << "序列化后:" << out << endl;
        return true;
#else
        Json::Value root; // Value是一种万能对象，接收任意的kv类型
        root["x"] = _x;
        root["op"] = _op;
        root["y"] = _y;
        Json::FastWriter writer; // 用来序列化的
        // Json::StyledWriter writer;
        out = writer.write(root);
        return true;
#endif
    }

    // string->struct
    bool Deserialization(const string &in)
    {
#ifdef MYSELF
        // inStr : 10 + 20 => [0]=>10, [1]=>+, [2]=>20
        vector<string> data;
        Util::StringSplit(in, SEP, data);
        if (data.size() != 3)
        {
            for (auto e : data)
            {
                cout << e << endl;
            }
            return false;
        }

        _x = atoi(data[0].c_str());
        _op = data[1][0];
        _y = atoi(data[2].c_str());
        cout << "反序列化后："
             << "_x:" << _x << " "
             << "_op:" << _op << " "
             << "_y:" << _y << endl;
        return true;
#else
        Json::Value root;
        Json::Reader reader;
        reader.parse(in, root);
        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _op = root["op"].asInt();
        return true;
#endif
    }

    int _x;
    int _y;
    char _op;
};

class Response
{
public:
    Response()
    {
    }

    Response(int result, int code)
        : _result(result), _code(code)
    {
    }

    // struct->string
    bool Serialize(string &out)
    {
#ifdef MYSELF
        out.clear();
        string stringres = to_string(_result);
        string stringcd = to_string(_code);
        out = stringres + SEP + stringcd;
        cout << "序列化后:" << out << endl;
        return true;
#else
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;
        Json::FastWriter writer;
        out = writer.write(root);
        return true;
#endif
    }

    // string->struct
    bool Deserialization(const string &in)
    {
#ifdef MYSELF
        vector<string> data;
        Util::StringSplit(in, SEP, data);
        if (data.size() != 2)
        {
            return false;
        }
        _result = atoi(data[0].c_str());
        _code = atoi(data[1].c_str());
        cout << "反序列化后："
             << "_result:" << _result << " "
             << "_code:" << _code << endl;
        return true;
#else
        Json::Value root;
        Json::Reader reader;
        reader.parse(in,root);
        _result=root["result"].asInt();
        _code=root["code"].asInt();
        return true;
#endif
    }

    int _result;
    int _code;
};